iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
2
Security

我是誰?我在哪?系列 第 19 篇

簡介 JWS

  • 分享至 

  • xImage
  •  

JWS 的全名為 JSON Web Signature,定義在 RFC 7515 裡面,主要定義了資訊的格式以及序列化(serialization)的方法。從名字可以看得出,它有使用到[數位簽章][Day 11]技術,或是它也可以使用[訊息驗證碼][Day 10]來確保資料的來源以及完整性。

JWS 包含了三組內容:

  • JOSE Header
  • JWS Payload
  • JWS Signature

JOSE Header 裡則是由下列兩種 Header 聯集而成

  • JWS Protected Header
  • JWS Unprotected Header

JWS Payload 一般會存放 claim。JWS Signature 則是依演算法對 JWS Protected Header 與 JWS Payload 做簽章後,再編碼的內容。如果演算法為 none 的話,則 JWS Signature 會是一個空字串。

而序列化的方法有兩種:

  • JWS Compact Serialization
  • JWS JSON Serialization

JWS 需要了解的主要是 JOSE Header 的定義、序列化的方式、以及如何驗證簽章。

JOSE Header

與 claim 類似,JOSE Header 也分為三類:

  1. Registered Header Parameter,RFC 裡預定義的 Header
  2. Public Header Parameter,在 IANA - JSON Object Signing and Encryption (JOSE) 公開註冊表上的 Header
  3. Private Header Parameter,除了上面兩種以外的 Header,通常是產生 JWS 與使用 JWS 雙方私下的協議,但不建議使用

而在 section 4.1 有列出預定義的 JOSE Header 有哪些,以下是比較常見的:

Header Full name 中文
alg Algorithm 簽章演算法,比方說 RS256
jku JWK Set URL 一個可以拿到 JWK Set 的 URL
jwk JSON Web Key 一個代表 JWK 的 JSON 資料
kid Key ID 如果有多個 JWK,則此 kid 應該會與某個 JWK 的 kid 相同
typ Type 這個 token 的格式,一般會設定成 JWT
cty Content type 一般不會設定,但如果 payload 裡面是另一個 JWT 時,這裡可以設定成 JWT
crit Critical 值為一個陣列,內容為 Header Name,主要目的是讓接受者檢查關鍵的 Header 是否支援

筆者對 X.509 不熟,且這次鐵人賽應該沒時間研讀,所以相關的資訊會先跳過。

而 JWS Protected Header 與 JWS Unprotected Header 的差別為:

Header Type 完整性保護 序列化支援
JWS Protected Header 有 JWS Compact Serialization / JWS JSON Serialization
JWS Unprotected Header 無 JWS JSON Serialization

Serialization

傳輸資料時,通常都會做序列化。方法有兩種,一種是精簡格式 JWS Compact Serialization ,也就是類似 xxx.yyy.zzz 這個樣子:

BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)

另一種則是 JWS JSON Serialization,內容只有 JSON encode,裡面又分 General 和 Flattened 兩種格式。

General 大概長的像下面這樣

{
    "payload": "<payload contents>",
    "signatures": [
        {
            "protected": "<integrity-protected header 1 contents>",
            "header": "<non-integrity-protected header 1 contents>",
            "signature": "<signature 1 contents>"
        },
        {
            "protected": "<integrity-protected header n contents>",
            "header": "<non-integrity-protected header n contents>",
            "signature": "<signature n contents>"
        }
    ]
}

Flattened 則有點像 Compact 的 JSON 版:

{
    "payload": "<payload contents>",
    "protected": "<integrity-protected header contents>",
    "header": "<non-integrity-protected header contents>",
    "signature": "<signature contents>"
}

從上面的格式也可以發現,JWS 是有支援放多個簽章的。但只有 General JWS JSON Serialization 支援。

下面是一個簡單的序列化比較表:

Serialization 支援 JWS Unprotected Header 多個簽章 URL 安全 大小
JWS Compact Serialization No No Yes 小
General JWS JSON Serialization Yes Yes No 大
Flattened JWS JSON Serialization Yes No No 中

從這個比較表可以知道 General 資訊比 Flattened 或 Compact 都來得完整,但就會大很多;而使用 JSON Serialization 時,會有編碼上的問題,所以 HTTP 傳輸通常還是 Compact 比較常見。

參考資料


上一篇
JWT 概觀
下一篇
簡介 JWE
系列文
我是誰?我在哪? 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言